package com.ross.mode.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Random;

/**
 * @version 1.0.0
 * @className: Tank
 * @description: JDK 动态代理
 * @author: zhangjunfa
 * @date: 2023/3/30 18:25
 */
public class TankJdk implements Movable {
    public void move() {
        System.out.println("我要跑步，跑了1KM");
        // try {
        //     Thread.sleep(new Random().nextInt(9000));
        // } catch (InterruptedException e) {
        //     e.printStackTrace();
        // }
    }

    public static void main(String[] args) {
        TankJdk tank = new TankJdk();
        // reflection 反射 通过二进制字节码分析类的属性和方法

        // System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        //newProxyInstance: 创建代理对象
        // 参数一: 被代理类对象
        // 参数二：接口类对象  被代理对象所实现的接口
        // 参数三：调用处理器。 被调用对象的那个方法被调用后该如何处理
        Movable movable = (Movable) Proxy.newProxyInstance(
                TankJdk.class.getClassLoader(),
                new Class[]{Movable.class},
                new LogProxy(tank)
        );
        movable.move();
    }
}

class LogProxy implements InvocationHandler {
    private Movable movable;

    public LogProxy(Movable movable) {
        this.movable = movable;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("跑步:" + method.getName() + "()执行前");
        // 此处相当于 movable.move()
        Object invoke = method.invoke(movable, args);
        System.out.println("跑步:" + method.getName() + "()执行后");
        return invoke;
    }
}


interface Movable {
    void move();
}